package com.zmn.mcc.business.impl.staff.ip;

import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.mcc.business.interfaces.staff.ip.StaffIpInfoBService;
import com.zmn.mcc.model.entity.log.IpInfo;
import com.zmn.mcc.model.entity.staff.log.IpInfoVo;
import com.zmn.tapi.common.baidu.LocationByIPResult;
import com.zmn.tapi.dubbo.interfaces.baidu.BaiduMapRemoteService;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author liubodong
 * @since 2021/01/28 22:22
 */
@Service
public class StaffInInfoBServiceImpl implements StaffIpInfoBService {

    @Resource
    MongoTemplate mongoTemplate;

    @DubboReference(version = com.zmn.tapi.dubbo.DubboConsts.INTERFACE_VERSION, check = false)
    BaiduMapRemoteService baiduMapRemoteService;

    /**
     * 描述: 员工操作日志mongo 标识
     */
    public final static String STAFF_IP_INFO = "staff_ip_info";


    @Override
    public void insertIpInfo(List<IpInfo> ipInfoList) {
        mongoTemplate.insert(ipInfoList, STAFF_IP_INFO);
    }

    @Override
    public List<IpInfoVo> listIpInfo(List<String> ipList) {
        if (CollectionUtil.isNullOrEmpty(ipList)) {
            return new ArrayList<>();
        }
        List<IpInfo> ipInfoList = listLocalIpInfo(ipList);
        List<String> localIpList = ipInfoList.stream().map(IpInfo::getIp).distinct().collect(Collectors.toList());
        //需要远程调用的ip集合
        Set<String> remoteCallIpList = ipList.stream().filter(e -> !localIpList.contains(e)).collect(Collectors.toSet());

        List<IpInfo> insertList = new ArrayList<>(10);
        if (CollectionUtil.isNullOrEmpty(remoteCallIpList)) {
            return convertVo(ipInfoList);
        }
        for (String ip : remoteCallIpList) {
            IpInfo ipInfo = locationByIP(ip);
            if (null == ipInfo) {
                continue;
            }
            ipInfoList.add(ipInfo);
            insertList.add(ipInfo);
        }
        //mongodb保存新数据
        insertIpInfo(insertList);

        return convertVo(ipInfoList);
    }

    @Override
    public IpInfo locationByIP(String ip) {
        if (StringUtils.isEmpty(ip) || LOCAL_IP.equals(ip) || ip.contains(INTRANET)) {
            return null;
        }
        ResponseDTO<LocationByIPResult> resp = baiduMapRemoteService.locationByIP(ip);
        if (null != resp || null != resp.getData()) {
            LocationByIPResult locationByIPResult = resp.getData();
            IpInfo ipInfo = new IpInfo();
            BeanUtils.copyProperties(locationByIPResult, ipInfo);
            ipInfo.setIp(ip);
            return ipInfo;
        }
        return null;
    }

    /**
     * 从mongodb查询已经存在的ip信息
     * @param ipList
     * @return
     */
    private List<IpInfo> listLocalIpInfo(List<String> ipList) {
        Query queryMongo = new Query();
        queryMongo.addCriteria(Criteria.where("ip").in(ipList));
        List<IpInfo> ipInfoList = mongoTemplate.find(queryMongo, IpInfo.class, STAFF_IP_INFO);
        return  ipInfoList;
    }

    /**
     * 转换VO对象
     * @param ipInfoList
     * @return
     */
    private List<IpInfoVo> convertVo(List<IpInfo> ipInfoList) {
        if (CollectionUtil.isNullOrEmpty(ipInfoList)) {
            return new ArrayList<>();
        }
        List<IpInfoVo> result = ipInfoList.stream().map(e -> {
            IpInfoVo ipInfoVo = new IpInfoVo();
            BeanUtils.copyProperties(e, ipInfoVo);
            return ipInfoVo;
        }).collect(Collectors.toList());
        return result;
    }
}
